package com.linshidream.intrachat.simplenio.pipeline.context;

import com.linshidream.intrachat.simplenio.pipeline.handler.MiniChannelHandler;
import com.linshidream.intrachat.simplenio.pipeline.handler.MiniChannelInboundHandler;
import com.linshidream.intrachat.simplenio.pipeline.handler.MiniChannelOutboundHandler;
import com.linshidream.intrachat.simplenio.pipeline.hearbeat.MiniIdleStateHandler;

import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.util.ArrayList;
import java.util.List;

/**
 * Created on 2025/8/19 19:39
 *
 * @author linshidream
 * @version 1.0.0
 * @description 责任链对象
 */

public class MiniChannelPipeline {

    private final MiniChannel channel;

    /**
     * 处理器持有对象。使用数组保存，每个处理器属于责任链上一个节点
     */
    private final List<MiniHandlerContext> contexts = new ArrayList<>();


    public MiniChannelPipeline(MiniChannel channel) {
        this.channel = channel;
    }

    public int contextsSize() {
        return contexts.size();
    }

    /**
     * 追加处理器
     *
     * @param handler
     * @return
     */
    public MiniChannelPipeline addLast(MiniChannelHandler handler) {
        //  int index 就是该处理器持有对象在 数组上的位置
        contexts.add(new MiniHandlerContext(handler, channel, this, contexts.size()));
        return this;
    }

    public MiniChannelPipeline addLast(String name, MiniChannelHandler handler) {
        //  int index 就是该处理器持有对象在 数组上的位置
        contexts.add(new MiniHandlerContext(name, handler, channel, this, contexts.size()));
        return this;
    }

    protected void fireChannelActive(int index) {
        // 处理到最后一个 结束
        if (index >= contexts.size()) {
            return;
        }
        MiniHandlerContext context = contexts.get(index);
        MiniChannelHandler handler = context.handler();

        // 入站处理器
        if (handler instanceof MiniChannelInboundHandler) {
            ((MiniChannelInboundHandler) handler).channelActive(context);
        } else {
            // 继续传播事件 知道最后一个环结束
            fireChannelActive(index + 1);
        }
    }

    protected void fireChannelRead(Object msg, int index) {
        // 处理到最后一个 结束
        if (index >= contexts.size()) {
            return;
        }
        MiniHandlerContext context = contexts.get(index);
        MiniChannelHandler handler = context.handler();

        // 入站处理器
        if (handler instanceof MiniChannelInboundHandler) {
            ((MiniChannelInboundHandler) handler).channelRead(context, msg);
        } else {
            // 继续传播事件 知道最后一个环结束
            fireChannelRead(msg, index + 1);
        }
    }


    protected void fireChannelInactive(int index) {
        // 处理到最后一个 结束, 并关闭通道
        if (index >= contexts.size()) {
            try {
                channel.setInAvtive();
                channel.socketChannel().close();
            } catch (Exception e) {
                fireExceptionCaught(e, index);
            }
            return;
        }
        MiniHandlerContext context = contexts.get(index);
        MiniChannelHandler handler = context.handler();

        // 入站处理器
        if (handler instanceof MiniChannelInboundHandler) {
            ((MiniChannelInboundHandler) handler).channelInactive(context);
        } else {
            // 继续传播事件 知道最后一个环结束
            fireChannelInactive(index + 1);
        }
    }


    protected void fireExceptionCaught(Throwable t, int index) {
        // 处理到最后一个 结束
        if (index >= contexts.size()) {
            return;
        }
        MiniHandlerContext context = contexts.get(index);
        MiniChannelHandler handler = context.handler();

        // 入站处理器
        if (handler instanceof MiniChannelInboundHandler) {
            ((MiniChannelInboundHandler) handler).exceptionCaught(context, t);
        } else {
            // 继续传播事件 知道最后一个环结束
            fireExceptionCaught(t, index + 1);
        }
    }


    protected void fireUserEventTriggered(Object evt, int index) {
        // 处理到最后一个 结束
        if (index >= contexts.size()) {
            return;
        }
        MiniHandlerContext context = contexts.get(index);
        MiniChannelHandler handler = context.handler();

        // 入站处理器
        if (handler instanceof MiniChannelInboundHandler) {
            ((MiniChannelInboundHandler) handler).userEventTriggered(context, evt);
        } else {
            // 继续传播事件 知道最后一个环结束
            fireUserEventTriggered(evt, index + 1);
        }
    }


    /**
     * 空闲检测
     */
    public void fireIdleCheck() {
        // 一个通道的所有处理器
        for (MiniHandlerContext ctx : contexts) {
            if (ctx.handler() instanceof MiniIdleStateHandler) {
                ((MiniIdleStateHandler) ctx.handler()).checkIdle(ctx);
            }
        }
    }

    protected void fireChannelWrite(Object msg, int index) {
        // 处理到第一个 ，需要将最终结果写入到通道，然后结束
        if (index < 0) {
            try {
                channel.outQueue().add((ByteBuffer) msg);

                // 注册写事件，让 selector 在下次循环时写数据
                SelectionKey key = channel.socketChannel().keyFor(channel.selector());
                key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);

            } catch (Exception e) {
                fireExceptionCaught(e, index);
            }
            return;
        }
        MiniHandlerContext context = contexts.get(index);
        MiniChannelHandler handler = context.handler();

        // 出站处理器
        if (handler instanceof MiniChannelOutboundHandler) {
            ((MiniChannelOutboundHandler) handler).channelWrite(context, msg);
        } else {
            // 继续传播事件 知道最后一个环结束
            fireChannelWrite(msg, index - 1);
        }
    }


}
